#pragma once

#include <condition_variable>
#include <mutex>
#include <vector>
#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>

#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastrtps/subscriber/SampleInfo.h>

#include "idl/CommonData.h"
#include "idl/CommonDataPubSubTypes.h"

class BaseClient
{
    class Listener : public eprosima::fastdds::dds::DataReaderListener
    {
        public:
            // variables
            eprosima::fastrtps::rtps::WriteParams write_params;
            std::mutex reception_mutex;
            std::condition_variable reception_cv;
            std::string response;
            bool received_replay = false;

            // functions
            void on_data_available(eprosima::fastdds::dds::DataReader* reader) override;

    };

public:
    bool init();
    void deinit();

protected:
    eprosima::fastdds::dds::DomainParticipant* participant_ = nullptr;
    eprosima::fastdds::dds::Publisher* publisher_ = nullptr;
    eprosima::fastdds::dds::Subscriber* subscriber_ = nullptr;
    eprosima::fastdds::dds::Topic* request_topic_ = nullptr;
    eprosima::fastdds::dds::Topic* reply_topic_ = nullptr;
    eprosima::fastdds::dds::DataWriter* request_writer_ = nullptr;
    eprosima::fastdds::dds::DataReader* reply_reader_ = nullptr;
    eprosima::fastdds::dds::TypeSupport request_type_;
    eprosima::fastdds::dds::TypeSupport reply_type_;

    BaseClient::Listener _listener;

};

